from flask import current_app, jsonify
from flask import g
from flask import render_template
from flask import request
from flask import session
from flask_session import Session

from info import constants, db
from info.models import User, News, Category, Comment, CommentLike
from info.utitls.response_code import RET
from . import newsdetail_bp
from info.utitls.common import user_login_data

@newsdetail_bp.route("/comment_like", methods=["POST"])
@user_login_data
def comment_like():
    # 获取参数
    #       user:用户对象， comment_id： 评论id  action：点赞或取消行为
    # 参数校验
    #        非空判断
    #           约定行为
    # 逻辑处理
    #       comment_id查询除当前评论对象
    #       根据action行为点赞或取消点赞
    # 点赞： 创建CommentLike对象， 将属性赋值
    # 取消点赞： CommentLike对象从数据库中删除
    # 返回值

    #   登陆成功
    user = g.user
    if not user:
        current_app.logger.error("用户未登录")
        return jsonify(errno=RET.SESSIONERR, errmsg="用户未登录")
    param_dict = request.json
    comment_id = param_dict.get("comment_id")
    action = param_dict.get("action")
    if not all([comment_id, action]):
        return jsonify(errno=RET.PARAMERR, errmsg="参数不足")
    if action not in ["add", "remove"]:
        current_app.logger.error("参数错误")
        return jsonify(errno=RET.PARAMERR, errmsg="参数错误")
    try:
        comment = Comment.query.get(comment_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="查询评论对象异常")
    if not comment:
        return jsonify(errno=RET.NODATA, errmsg="评论不存在")
    if action == "add":
        comment_like = None
        try:
            comment_like = CommentLike.query.filter(CommentLike.comment_id == comment_id,CommentLike.user_id == user.id).first()
        except Exception as e:
            current_app.logger.error(e)
            return jsonify(errno=RET.DBERR, errmsg="查询评论点赞对象异常")
        if not comment_like:
            # 点赞对象
            comment_like_obj = CommentLike()
            # 当前用户点赞
            comment_like_obj.user_id = user.id
            # 对当前评论点赞
            comment_like_obj.comment_id = comment_id
            # 点赞数量累加
            comment.like_count += 1
            db.session.add(comment_like_obj)

    else:
        comment_like = None
        try:
            comment_like = CommentLike.query.filter(CommentLike.comment_id == comment_id,
                                                    CommentLike.user_id == user.id).first()
        except Exception as e:
            current_app.logger.error(e)
            return jsonify(errno=RET.DBERR, errmsg="查询评论点赞对象异")
        # 当前用户点赞了
        if comment_like:
            db.session.delete(comment_like)
            comment.like_count -= 1
    try:
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR, errmsg="提交数据异常")
    return jsonify(errno=RET.OK, errmsg="ok")




@newsdetail_bp.route("/news_comment", methods=["POST"])
@user_login_data
def news_comment():
    # 获取参数
    #     user:当前登陆的用户   news_id： 新闻id  comment：评论内容， parent——id： 主评论id

    # 校验参数
    #      非空判断
    # 逻辑处理
    #       根据news_id查询出新闻对象
    #       创建评论模型
    #       保存到数据库
    # 返回值
    #       登录成功
    user = g.user
    if not user:
        current_app.logger.error("用户未登陆")
        return jsonify(errno=RET.SESSIONERR, errmsg="用户未登陆")


    param_dict = request.json
    news_id = param_dict.get("news_id")
    comment_str = param_dict.get("comment")
    # 如果有值表示是子评论，反之就是主评论
    parent_id = param_dict.get("parent_id")

    if not all([news_id, comment_str]):
        current_app.logger.error("参数不足")
        return jsonify(errno=RET.PARAMERR, errmsg="参数不足")

    try:
        news = News.query.get(news_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="查询新闻对象异常")
    if not news:
        return jsonify(errno=RET.NODATA, errmsg="新闻不存在，不能发表评论")
    # 创建评论模型
    comment = Comment()
    # 那个用户评论
    comment.user_id = user.id
    # 评论那条新闻
    comment.news_id = news.id
    # 评论的内容
    comment.content = comment_str
    if parent_id:
        comment.parent_id = parent_id
        # 子评论
    try:
        db.session.add(comment)
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR, errmsg="保存评论对象异常")
    # 组织data

    return jsonify(errno=RET.OK, errmsg="ok", data=comment.to_dict())





# 收藏/取消收藏接口
@newsdetail_bp.route("/news_collect", methods=["POST"])
@user_login_data
def news_collect():
    """
    1 获取参数，
        1.1 news_id ： 新闻id  user： 当前登陆的用户对象  action： 收藏/取消收藏的行为
    2 校验参数
        2.1 非空判断
        2.2 约定action行为 ： action in["collect", "cancel_collect"]
    3. 逻辑处理
        3.1 根据新闻id获取新闻对象
        3.2 根据action行为 判断是否收藏
        收藏： 将新闻对象添加到用户的收藏列表中
        取消收藏： 奖新闻对象从收藏列表中删除
        3.3 将修改操作保存到数据库中
    4。 返回值
        登陆成功


    """
    # 获取当前登陆用户
    user = g.user
    if not user:
        current_app.logger.error("用户未登录")
        return jsonify(errno=RET.SESSIONERR, errmsg="用户未登录")


    params_dict = request.json
    news_id = params_dict.get("news_id")
    action = params_dict.get("action")
    if not all([news_id, action]):
        current_app.logger.error("参数不足")
        return jsonify(errno=RET.PARAMERR, errmsg="参数错误")
    if action not in ["collect", "cancel_collect"]:
        current_app.logger.error("参数错误")
        return jsonify(errno=RET.PARAMERR, errmsg="参数错误")
    # 逻辑判断
    try:
        news = News.query.get(news_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="查询新闻对象异常")
    if not news:
        return jsonify(errno=RET.NODATA, errmsg="新闻不存在")
    if action:
        user.collection_news.append(news)
    else:
        # 如果新闻在收藏列表中
        if news in user.collection_news:
            user.collection_news.remove(news)
    try:
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR, errmsg="查询用户对象异常")
    return jsonify(errno=RET.OK, errmsg="ok")



# 127.0.0.1/news/1    1: 代表新闻id
@newsdetail_bp.route("/<int:news_id>")
@user_login_data
def get_news_detail(news_id):
    # 展示新闻详情页面
    # 获取当前登陆用户的user——id
    user = g.user
    # if user:
    #     user_dict = user.to_dict()
    # 与user.to_dict() if user else None效果相同

    # 首页数据字典

    # 2新闻点击排行数据
    # news_rank_list = News.query.order_by(News.clicks.desc()).limit(constants.CLICK_RANK_MAX_NEWS)
    # 新闻对象列表转化为字典列表
    try:
        news_rank_list = News.query.order_by(News.clicks.desc()).limit(constants.CLICK_RANK_MAX_NEWS)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="查询新闻数据异常")
    news_dict_list = []
    for news_obj in news_rank_list if news_rank_list else []:
        news_dict = news_obj.to_dict()
        news_dict_list.append(news_dict)
    # 根据新闻id查询新闻数据
    try:
        news = News.query.get(news_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="查询新闻对象异常")
    # 新闻对象转字典
    if news:
        news_dict = news.to_dict()
    # 4.当前用户是否有收藏该新闻
    # 表示当前用户是否收藏过该新闻 默认false： 没有收藏
    # 当前新闻是否在当前用户新闻搜藏列表中
    is_collected = False
    # 如果存在user再判断，前面设置了为user = none 所以要判断
    if user:
        if news in user.collection_news:
            is_collected = True
    # 5 获取新闻评论列表
    try:
        news_comment_list = Comment.query.filter(Comment.news_id == news_id).order_by(Comment.create_time.desc()).all()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="查询用户对象异常")
    # 6 获取当前用户对那条评论点过赞
    # 评论列表
    if user:
        comment_id_list = [comment.id for comment in news_comment_list]
        try:
            commentlike_obj_list = CommentLike.query.filter(CommentLike.comment_id.in_(comment_id_list), CommentLike.user_id == user.id).all()
        except Exception as e:
            current_app.logger.error(e)
            return jsonify(errno=RET.DBERR, errmsg="查询用户对象异常")
        commentlike_id_list = [commentlike_obj.comment_id for commentlike_obj in commentlike_obj_list]

    #     对象列表转字典列表
    comment_dict_list = []
    for comment_obj in news_comment_list if news_comment_list else []:
        # 转字典
        comment_dict = comment_obj.to_dict()
        if comment_obj.id in commentlike_id_list:
            comment_dict["is_like"] = True
        comment_dict_list.append(comment_dict)


    data={
        "user_info": user.to_dict() if user else None,
        "news_rank_list": news_dict_list,
        "news": news_dict,
        "is_collected": is_collected,
        "comments": comment_dict_list
    }
    # return render_template("news/index.html", data=data)
    #
    # # data = {}
    return render_template("news/detail.html", data=data)